package io.sage.modules.sensor;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import io.sage.common.config.SerialPortManager;
import io.sage.common.config.WebSocketServer;
import io.sage.common.serialport.exception.SendDataToSerialPortFailure;
import io.sage.common.serialport.exception.SerialPortOutputStreamCloseFailure;
import io.sage.common.utils.MyUtils;
import io.sage.common.utils.R;
import io.sage.common.utils.SpringContextUtils;

@RestController("SensorController")
@RequestMapping("sensor/sensor")
public class SensorController implements Job{
	
	private List<String> commList = null;
	
	private SerialPort serialport;
	
	private String wsd = "";
	
	public SerialPort getSerialport() {
		return serialport;
	}

	/**
	 * 获取所有的可用串口
	 * @param params
	 * @return
	 */
	@ResponseBody
	@GetMapping("/commList")
	public R commList(@RequestParam Map<String, Object> params) {
		
		commList = SerialPortManager.findPort();
		// 检查是否有可用串口，有则加入选项中
		if (commList == null || commList.size() < 1) {
			return R.error("没有搜索到有效串口！");
		} else {
			HashMap<String, Object> paramMap = new HashMap<String, Object>();
			ArrayList<Object> baudrateList=new ArrayList<>();
			baudrateList.add(9600);
			baudrateList.add(19200);
			baudrateList.add(38400);
			baudrateList.add(57600);
			baudrateList.add(115200);
			paramMap.put("commList", commList);
			//波特率
			paramMap.put("baudrateList", baudrateList);
			
			return R.ok().put("paramMap", paramMap);
		}
		
	}
	
	/**
	 * 打开串口
	 * 
	 */
	@ResponseBody
	@RequestMapping("/openSerialPort")
	private R openSerialPort(@RequestParam Map<String, Object> params) throws Exception {


		// 获取串口名称
//		String commName = (String) commChoice.getSelectedItem();
		String commName = (String) params.get("commName");
		// 获取波特率
		int baudrate = 9600;
//		String bps = (String) baudrateChoice.getSelectedItem();
		String bps = (String) params.get("bps");
		baudrate = Integer.parseInt(bps);

		// 检查串口名称是否获取正确
		if (commName == null || commName.equals("")) {
			return R.error("没有搜索到有效串口！");
		} else {
			try {
				serialport = SerialPortManager.openPort(commName, baudrate);
				if (serialport != null) {
					System.out.println("串口已经打开");
				}
			} catch (Exception e) {
				e.printStackTrace();
				return R.error("串口被占用");
			}
		}

		try {
			SerialPortManager.addListener(serialport, new SerialListener());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return R.ok("串口已打开");
	}
	
	/**
	 * 关闭串口
	 * 
	 */
	@ResponseBody
	@RequestMapping("/closeSerialPort")
	private R closeSerialPort() {
		SerialPortManager.closePort(serialport);
		serialport = null;
		return R.ok("串口已关闭");
	}
	
	
	
	/**
	 * 发送指定数据
	 * 
	 */
	@ResponseBody
	@GetMapping("/sendData")
	private R sendData(String data) {
		try {
			SerialPortManager.sendToPort(serialport, MyUtils.HexString2Bytes(data));
			
			return R.ok();
		} catch (SendDataToSerialPortFailure e) {
			e.printStackTrace();
		} catch (SerialPortOutputStreamCloseFailure e) {
			e.printStackTrace();
		}
		return R.error();
	}
	
	private class SerialListener implements SerialPortEventListener {
		/**
		 * 处理监控到的串口事件
		 */
		public void serialEvent(SerialPortEvent serialPortEvent) {

			switch (serialPortEvent.getEventType()) {

			case SerialPortEvent.BI: // 10 通讯中断
				R.error("与串口设备通讯中断");
				break;

			case SerialPortEvent.OE: // 7 溢位（溢出）错误

			case SerialPortEvent.FE: // 9 帧错误

			case SerialPortEvent.PE: // 8 奇偶校验错误

			case SerialPortEvent.CD: // 6 载波检测

			case SerialPortEvent.CTS: // 3 清除待发送数据

			case SerialPortEvent.DSR: // 4 待发送数据准备好了

			case SerialPortEvent.RI: // 5 振铃指示

			case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
				break;

			case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
				byte[] data = null;
				try {
					if (serialport == null) {
						R.error("串口对象为空！监听失败！");
					} else {
						// 读取串口数据
						data = SerialPortManager.readFromPort(serialport);
						wsd = MyUtils.byteArray2HexString(data, data.length, true);
						R wsd2 = MyUtils.getWsd(wsd);
						wsd2.put("time", new Date());
						System.out.println("温湿度数据为："+wsd);
						
						WebSocketServer.sendInfo(JSONObject.toJSONString(wsd2),"7");
						// R.ok(byteArray2HexString);
//						dataShow(MyUtils.byteArray2HexString(data, data.length, true), STYLE_NORMAL);
					}
				} catch (Exception e) {
					R.error(e.toString());
					// 发生读取错误时显示错误信息后退出系统
					System.exit(0);
				}
				break;
			}
		}
	}

	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		try {
			/**
			 * 固定返回温湿度的字符串.
			 */
			String data="01 04 00 00 00 02 71 CB";
			SensorController s = (SensorController)SpringContextUtils.getBean("SensorController");
			SerialPort serialport1 = s.getSerialport();
			SerialPortManager.sendToPort(serialport1, MyUtils.HexString2Bytes(data));
		} catch (SendDataToSerialPortFailure e) {
			e.printStackTrace();
		} catch (SerialPortOutputStreamCloseFailure e) {
			e.printStackTrace();
		}
		
	}

}
